package com.kun.demo05_threadCommunication;


import org.junit.Test;

//生产者消费者问题--解决方式1：使用缓冲区，管程法
public class Solution01 {

    //1，定义产品
    class Product{int id;}

    //2. 定义消费者
    class Consumer extends Thread{

        private Buffer buffer;

        @Override
        public void run() {
            //消费
            for (int i = 0; i < 10; i++) {
                Product product = buffer.pop();
                System.out.println("消费者消费了产品：" + product.id);
            }
        }
    }

    //3. 定义生产者
    class Producer extends Thread{

        private Buffer buffer;

        @Override
        public void run() {
            for (int i = 0; i < 10; i++) {
                Product product = new Product();
                product.id = i;
                buffer.push(product);
                System.out.println("生产者生产了产品：" + product.id);
            }
        }
    }

    //4. 定义缓冲区
    class Buffer{
        private Product[] products = new Product[5];
        private int currentSize=0; //指向下一个空闲位置

        //生产者--生产
        public synchronized void push(Product product){
            //1. 判断缓冲区是否已满
            if (currentSize == products.length){
                //1.1 等待消费者消费
                try {
                    this.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }

            //2. 缓冲区未满，放入产品
            products[currentSize++] = product;

            //3. 通知消费者消费
            this.notifyAll();
        }

        //消费者--消费
        public synchronized Product pop(){
            //1. 判断缓冲区是否为空
            if (currentSize == 0){
                //1.1 等待生产者生产
                try {
                    this.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }

            //2. 缓冲区不为空，取出产品
            Product product = products[--currentSize];

            //3. 通知生产者生产
            this.notifyAll();

            return product;
        }

    }

    @Test
    public void test() throws InterruptedException {
        Buffer buffer = new Buffer();
        Producer producer = new Producer();
        Consumer consumer = new Consumer();

        producer.buffer = buffer;
        consumer.buffer = buffer;

        producer.start();
        consumer.start();

        Thread.sleep(10_000);
    }




}
